package bb.lanxing.activity.sport;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.baidu.platform.comapi.map.MapBundleKey;
import com.umeng.analytics.MobclickAgent;

import org.litepal.LitePal;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import bb.lanxing.App;
import bb.lanxing.R;
import bb.lanxing.adapter.mine.HistoryListAdapter;
import bb.lanxing.adapter.mine.HistoryYearAdapter;
import bb.lanxing.common.config.UmengEventConst;
import bb.lanxing.lib.widget.SectionRecyclerScrollTabStrip;
import bb.lanxing.lib.widget.utils.Density;
import bb.lanxing.manager.SPConstant;
import bb.lanxing.manager.SharedManager;
import bb.lanxing.model.database.ProPerms;
import bb.lanxing.model.database.Workout;
import bb.lanxing.mvp.presetner.HistoryPresenterImpl;
import bb.lanxing.mvp.presetner.i.IHistoryPresenter;
import bb.lanxing.activity.base.BaseViewActivity;
import bb.lanxing.mvp.view.i.IHistoryListView;
import bb.lanxing.service.SyncTaskService;
import bb.lanxing.util.Enums;
import bb.lanxing.util.Log;
import bb.lanxing.util.WorkoutTitleUtil;
import bb.lanxing.view.BiciAlertDialogBuilder;
import bb.lanxing.view.BikeHeader;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

public class HistoryListActivity extends BaseViewActivity implements IHistoryListView,
        HistoryListAdapter.OnItemClickListener<Workout>, View.OnClickListener {
    private static final String TAG = "HistoryListActivity";

    public static final String EXTRA_SHOW_MODE = "choose_mode";

    private static final int REQUEST_DETAIL = 1;
    private static final int REQUEST_MERGE = 2;

    public static final int SHOW_MODE_NORMAL = 0;
    public static final int SHOW_MODE_SHARE = 1;
    public static final int SHOW_MODE_CHOOSE = 2;

    private Spinner yearsSpinner;
    private View badgeView;
    private View mMergeBadgeView;
    private SectionRecyclerScrollTabStrip scrollTabStrip;
    private PtrFrameLayout refreshView;
    private RecyclerView historyList;
    private HistoryListAdapter historyListAdapter;
    private LinearLayout mLlChoose;
    private TextView mTvWorkoutCount;
    private TextView chooseConfirmView;

    private long userId = 0L;
    private int showMode = SHOW_MODE_NORMAL;

    private IHistoryPresenter historyPresenter;

    private boolean openSync;

    private int unUploadCount;

    private List<Integer> years;

    private boolean showFlag = false;

    private int whereGetSportHistoryData = 0;

    private Workout mergeWorkout = null;
    private int distant = 0;

    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (1 != intent.getIntExtra(SyncTaskService.EXTRA_TASK_ID, 0)) {
                return;
            }
            if (SyncTaskService.ACTION_SYNC_WORKOUTS_START.equals(action)) {
                mergeWorkout = null;
                if (openSync) {
                    int intExtra = intent.getIntExtra("size", 0);
                    if (intExtra == 0) {
                        App.getContext().showMessage(R.string.sync_workout_none);
                        flushWorkoutState();
                        return;
                    }
                    showSyncDialog(1, intExtra);
                }
            } else if (SyncTaskService.ACTION_SYNC_WORKOUTS_FINISH.equals(action)) {
                if (openSync) {
                    int intExtra2 = intent.getIntExtra("fail_size", 0);
                    dismissLoadingDialog();
                    openSync = false;
                    historyPresenter.getMonthDesc(getCurrentYear(), userId, 2);
                    if (intExtra2 > 0) {
                        toast(getString(R.string.sync_workout_fail_result, intExtra2));
                    }
                    flushWorkoutState();
                    mergeWorkout = null;
                    return;
                }
                int intExtra3 = intent.getIntExtra("success_size", 0);
                ArrayList<Workout> arrayList = (ArrayList<Workout>) intent.getSerializableExtra(SyncTaskService.EXTRA_WORKOUTS);
                if (intExtra3 != 1 || arrayList == null || arrayList.isEmpty()) {
                    return;
                }
                mergeWorkout = arrayList.get(0);
                historyPresenter.getMonthDesc(getCurrentYear(), userId, 2);
            } else if (SyncTaskService.ACTION_SYNC_ITEM_RESULT.equals(action)) {
                if (openSync) {
                    if (intent.getBooleanExtra("success", false)) {
                        showSyncDialog(intent.getIntExtra(MapBundleKey.MapObjKey.OBJ_SL_INDEX, 1),
                                intent.getIntExtra("size", 0));
                    } else {
                        toast(R.string.sync_one_workout_fail);
                    }
                }
            } else if (SyncTaskService.ACTION_SYNC_ALREADY_SYNC.equals(action)) {
                mergeWorkout = null;
                Toast.makeText(getApplicationContext(), R.string.sync_waiting, Toast.LENGTH_SHORT).show();
            }
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_history_list);
        setupActionBar(true, -1, true);
        bindView(getWindow().getDecorView());

        if (App.getContext().isUserSignin()) {
            userId = App.getContext().getUserId();
        }

        Intent intent = getIntent();
        if (intent != null) {
            showMode = intent.getIntExtra(EXTRA_SHOW_MODE, 0);
        }
        if (showMode == SHOW_MODE_CHOOSE) {
            setTitle(R.string.workout_merge_title);
            mLlChoose.setVisibility(View.VISIBLE);
            mTvWorkoutCount.setText(getString(R.string.workout_merge_choose_count_btn, 0, 0));
            chooseConfirmView.setEnabled(false);
        } else {
            setTitle("");
            mLlChoose.setVisibility(View.GONE);
        }
        yearsSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                refreshView.refreshComplete();
                refreshView.postDelayed(() -> refreshView.autoRefresh(), 50L);
                historyListAdapter.clearData();
                scrollTabStrip.setUpRecyclerView(historyList, historyListAdapter, true);
                yearsSpinner.setEnabled(false);
                if (parent.getAdapter() instanceof HistoryYearAdapter) {
                    ((HistoryYearAdapter) parent.getAdapter()).setSelected(position);
                }
            }
        });

        BikeHeader bikeHeader = new BikeHeader(this);
        refreshView.setHeaderView(bikeHeader);
        refreshView.addPtrUIHandler(bikeHeader);
        refreshView.setPtrHandler(new PtrDefaultHandler() {
            @Override
            public void onRefreshBegin(PtrFrameLayout ptrFrameLayout) {
                int currentYear = getCurrentYear();
                if (currentYear < 0) {
                    refreshView.refreshComplete();
                } else {
                    if (getWhereGetSportHistoryData() == 0) {
                        int localOrServer = 0;
                        historyPresenter.getMonthDesc(currentYear, userId, localOrServer);
                        setWhereGetSportHistoryData(2);
                    } else {
                        int localOrServer = 2;
                        historyPresenter.getMonthDesc(currentYear, userId, localOrServer);
                    }
                }
            }
        });
        historyList.setLayoutManager(new LinearLayoutManager(this));
        historyListAdapter = new HistoryListAdapter(historyList);
        historyListAdapter.setOnItemClickListener(this);
        historyListAdapter.setChooseMode(showMode == SHOW_MODE_CHOOSE, 10);
        historyList.setAdapter(historyListAdapter);

        whereGetSportHistoryData = 0;

        historyPresenter = new HistoryPresenterImpl(this);
        historyPresenter.getYears(userId);

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(SyncTaskService.ACTION_SYNC_ITEM_RESULT);
        intentFilter.addAction(SyncTaskService.ACTION_SYNC_WORKOUTS_START);
        intentFilter.addAction(SyncTaskService.ACTION_SYNC_WORKOUTS_FINISH);
        intentFilter.addAction(SyncTaskService.ACTION_SYNC_ALREADY_SYNC);
        if (Build.VERSION.SDK_INT < 33) {
            registerReceiver(receiver, intentFilter);
        } else {
            registerReceiver(receiver, intentFilter, Context.RECEIVER_EXPORTED);
        }

        hideRedhot();
    }

    private void bindView(View bindSource) {
        yearsSpinner = bindSource.findViewById(R.id.history_years_spinner);
        badgeView = bindSource.findViewById(R.id.badgeView);
        mMergeBadgeView = bindSource.findViewById(R.id.merge_badge_view);
        scrollTabStrip = bindSource.findViewById(R.id.history_list_script);
        refreshView = bindSource.findViewById(R.id.refreshView);
        historyList = bindSource.findViewById(R.id.history_list);
        mLlChoose = bindSource.findViewById(R.id.ll_choose);
        mTvWorkoutCount = bindSource.findViewById(R.id.tv_workout_count);
        chooseConfirmView = bindSource.findViewById(R.id.history_choose_confirm);
    }

    private void hideRedhot() {
        //mMergeBadgeView.setVisibility(SharedManager.getInstance()
        //        .getBoolean(SPConstant.MERGE_WORKOUT_RED_HOT, true) ? View.VISIBLE : View.GONE);
    }

    @Override
    public boolean onItemClick(final int pos, Workout workout, View v, boolean isChecked) {
        if (workout == null) {
            return true;
        }
        if (workout.getFullDataValue() < 2) {
            workout = Workout.getById(workout.getId());
        }

        if (showMode == SHOW_MODE_NORMAL) {
            if (workout.getLocSource() == Workout.LOCATION_SOURCE_BICI && !workout.isSynchronise()) {
                toast(R.string.mine_history_toast_sync_bici_first);
                return true;
            } else if (workout.getLocSource() == Workout.LOCATION_SOURCE_XOSS_X2P) {//100
                goToDetail(workout, pos);
                return true;
            } else if (workout.getSport() == Workout.TYPE_INDOOR_BIKE
                    || workout.getSport() == Workout.TYPE_VIRTUAL_ACTIVITY
                    || workout.getSport() == Workout.TYPE_CROSS_TRAINER
                    || workout.getSport() == Workout.TYPE_ROWER
                    || workout.getSport() == Workout.TYPE_BIKE_TRAINER) {//11, 12
                goToDetail(workout, pos);
                return true;
            } else if (workout.getUserId() == 0) {
                goToDetail(workout, pos);
                return true;
            } else if (workout.getServerId() == 0) {
                //TODO:sun, do not delete for debug usage
                int sportType = workout.getSport();
                if (workout.getDistance() > 10) {//10 meters  //Utils.DOUBLE_EPSILON){
                    goToDetail(workout, pos);
                } else if ((Workout.TYPE_TRAINING == sportType)
                        || (Workout.TYPE_BIKE_TRAINER == sportType)
                        || (Workout.TYPE_ROWER == sportType)
                        || (Workout.TYPE_INDOOR_BIKE == sportType)
                        || (Workout.TYPE_CROSS_TRAINER == sportType)) {
                    goToDetail(workout, pos);
                } else {
                    historyListAdapter.removeItem(pos);

                    LitePal.delete(Workout.class, workout.getId());
                    App.getContext().showLongMessage(getString(R.string.mine_history_toast_invalid_workout));
                }
            } else {
                historyPresenter.checkDetailToGo(workout, pos);
            }
        } else if (showMode == SHOW_MODE_SHARE) {
            if (workout.getServerId() <= 0) {
                toast(R.string.mine_history_toast_cannot_share_donot_upload);
            } else if (workout.getHidden() != 0) {
                toast(R.string.mine_history_toast_cannot_share_hide);
            } else {
                confirmShare(workout);
            }
        } else if (showMode == SHOW_MODE_CHOOSE) {
            if (workout.getServerId() <= 0) {
                toast(R.string.mine_history_toast_cannot_merge);
                return false;
            }
            int selectedCount = historyListAdapter.getSelectedCount();
            int i;
            if (isChecked) {
                i = selectedCount + 1;
                distant = (int) (distant + workout.getDistance());
            } else {
                i = selectedCount - 1;
                distant = (int) (distant - workout.getDistance());
            }
            int i2;
            chooseConfirmView.setEnabled(i >= 2 && i <= 10 && (i2 = distant) > 0 && i2 <= 10000000);
            mTvWorkoutCount.setText(getString(R.string.workout_merge_choose_count_btn, i, distant / 1000));
        }
        return true;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_history_list, menu);
        MenuItem findItem = menu.findItem(R.id.menu_history_fit);
        MenuItem findItem2 = menu.findItem(R.id.menu_history_sync);
        findItem.setVisible(showMode != SHOW_MODE_CHOOSE);
        findItem2.setVisible(showMode != SHOW_MODE_CHOOSE);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int itemId = item.getItemId();
        if (itemId == R.id.menu_history_fit) {
            SharedManager.getInstance().setValue(SPConstant.MERGE_WORKOUT_RED_HOT, false);
            hideRedhot();
            if (App.getContext().isUserSignin()) {
                ProPerms proPerms = ProPerms.getProPerms();
                boolean debug = true; //TODO, hu, debug-Pro function
                if (/*proPerms != null && proPerms.getPerms().getWorkoutMerge() == 1*/debug) {
                    MobclickAgent.onEventValue(App.getContext(), UmengEventConst.V30_TRACE_LIST_MERGE, null, 1);
                    new BiciAlertDialogBuilder(this)
                            .setTitle(R.string.workout_merge_tips_title)
                            .setMessage(R.string.workout_merge_tips_msg)
                            .setPositiveButton(R.string.confirm, (dialog, which) -> startActivity(new Intent(getApplicationContext(), HistoryListActivity.class)
                                    .putExtra(EXTRA_SHOW_MODE, 2)))
                            .show();
                } else {
                    //TODO:hu, not need to check Pro from server
                    Log.d(TAG, "onOptionsItemSelected: not need to check Pro from server");
                }
            } else {
                App.getContext().userSignin();
            }
        } else if (itemId == R.id.menu_history_sync) {
            LocalWorkoutActivity.Companion.start(context);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
        historyPresenter.destroy();
    }

    @Override
    public void loadYears(List<Integer> list) {
        if (list != null && !list.isEmpty()) {
            years = list;
            yearsSpinner.setAdapter(new HistoryYearAdapter(this, R.layout.history_list_years, list));
            yearsSpinner.setSelection(list.size() - 1);
        }
    }

    @Override
    public void loadWorkoutList(int year, List<HistoryListAdapter.MonthDesc> monthDescList) {
        if (monthDescList != null) {
            historyListAdapter.addMonthData(true, monthDescList);
            LinearLayoutManager linearLayoutManager = (LinearLayoutManager) historyList.getLayoutManager();
            if (!monthDescList.isEmpty() && linearLayoutManager != null) {
                Workout workout = mergeWorkout;
                if (workout != null) {
                    int findItemPositionF = historyListAdapter.findItemPositionF(workout);
                    if (findItemPositionF > 0) {
                        linearLayoutManager.scrollToPositionWithOffset(findItemPositionF, Density.dp2px(this, 55.5f));
                    } else {
                        linearLayoutManager.scrollToPositionWithOffset(0, 0);
                    }
                } else {
                    linearLayoutManager.scrollToPositionWithOffset(0, 0);
                }
            }
            scrollTabStrip.setUpRecyclerView(historyList, historyListAdapter, true);
        }
        if (!yearsSpinner.isEnabled()) {
            refreshView.postDelayed(() -> yearsSpinner.setEnabled(true), 250L);
        }
        checkRedDotView(monthDescList);
    }

    public void checkRedDotView(List<HistoryListAdapter.MonthDesc> monthDescList) {
        if (monthDescList == null) {
            return;
        }
        int i = 0;
        for (HistoryListAdapter.MonthDesc monthDesc : monthDescList) {
            for (Workout workout : monthDesc.itemDataSet) {
                if (workout.getUploadStatus() != Enums.UploadStatus.Uploaded) {
                    i++;
                }
            }
        }
        if (i > 0) {
            badgeView.setVisibility(View.VISIBLE);
        } else {
            badgeView.setVisibility(View.GONE);
        }
        if (i < 3 || showFlag) {
            return;
        }
        showFlag = true;
        App.getContext().showMessage(R.string.mine_history_toast_upload_in_time);
    }

    private void confirmShare(final Workout workout) {
        new BiciAlertDialogBuilder(this)
                .setMessage(String.format(getString(R.string.dialog_content_share_workout), workout.getTitle()))
                .setNegativeButton(R.string.dialog_btn_no, null)
                .setPositiveButton(R.string.dialog_btn_share, (dialog, which) -> {
                    showMyProgressDialog(R.string.dialog_content_processing);
                    new Thread(() -> {
                        Intent intent = new Intent();
                        long serverId = workout.getServerId();
                        String uuid = workout.getUuid();
                        String title = !TextUtils.isEmpty(workout.getTitle()) ? workout.getTitle() : WorkoutTitleUtil.buildWorkoutDefaultTitle(this, workout);
                        int sport = workout.getSport();
                        intent.putExtra("workout_server_id", serverId);
                        intent.putExtra("workout_uuid", uuid);
                        intent.putExtra("workout_title", title);
                        intent.putExtra("workout_sport_type", sport);
                        setResult(-1, intent);
                        dismissLoadingDialog();
                        finish();
                    }).start();
                }).show();
    }

    @Override
    public void showSyncDialog(int index, int syncCount) {
        showLoadingDialog(getString(R.string.sync_workout_sync_progress, syncCount, index), true);
    }

    @Override
    public void stopListRefresh() {
        if (refreshView.isRefreshing()) {
            refreshView.refreshComplete();
        }
    }

    @Override
    public void closeRequestDialog() {
        super.closeRequestDialog();
    }

    @Override
    public int getCurrentYear() {
        int selectedItemPosition = yearsSpinner.getSelectedItemPosition();
        if (years == null || selectedItemPosition < 0 || selectedItemPosition >= years.size()) {
            return -1;
        }
        return years.get(selectedItemPosition);
    }

    public int getWhereGetSportHistoryData() {
        return whereGetSportHistoryData;
    }

    public void setWhereGetSportHistoryData(int whereGetSportHistoryData) {
        this.whereGetSportHistoryData = whereGetSportHistoryData;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == -1) {
            if (requestCode != REQUEST_DETAIL) {
                if (requestCode == REQUEST_MERGE) {
                    finish();
                    return;
                }
                return;
            }
            final int intExtra = data.getIntExtra("list_pos", -1);
            Long valueOf = data.getLongExtra("delete_workout_id", -1L);
            Long valueOf2 = data.getLongExtra("modify_workout_id", -1L);
            if (valueOf > 0) {
                if (intExtra >= 0) {
                    baseHandler.postDelayed(() -> {
                        HistoryListAdapter.MonthDesc monthItem = historyListAdapter.getMonthItem(intExtra);
                        if (!monthItem.itemDataSet.isEmpty()) {
                            historyPresenter.updateMonthInfo(userId, monthItem);
                        }
                        historyListAdapter.removeItem(intExtra);
                        checkRedDotView(historyListAdapter.getMonthDataSet());
                    }, 500L);
                    return;
                }
                historyListAdapter.removeItemById(valueOf);
                checkRedDotView(historyListAdapter.getMonthDataSet());
            } else if (valueOf2 > 0) {
                historyPresenter.updateMonthInfo(userId, historyListAdapter.getMonthItem(intExtra));
                Observable.just(valueOf2).subscribeOn(Schedulers.io())
                        .flatMap((Func1<Long, Observable<Workout>>) workoutId -> Observable.just(Workout.getById(workoutId)))
                        .observeOn(AndroidSchedulers.mainThread()).subscribe(workout -> {
                            historyListAdapter.updateItem(workout, intExtra);
                            checkRedDotView(historyListAdapter.getMonthDataSet());
                        });
            }
        }
    }

    @Override
    public void goToDetail(Workout workout, int position) {
        Intent intent = new Intent(this, SportRecordDetailActivity.class);
        intent.putExtra("workoutServerId", workout.getServerId());
        startActivity(intent);
    }

    @Override
    public void onMonthInfo(final HistoryListAdapter.MonthDesc desc) {
        historyListAdapter.updateMonth(desc);
    }

    public void flushWorkoutState() {
        if (historyListAdapter != null) {
            ArrayList<HistoryListAdapter.MonthDesc> monthDataSet = historyListAdapter.getMonthDataSet();
            LinkedList<Workout> linkedList = new LinkedList<>();
            for (HistoryListAdapter.MonthDesc monthDesc : monthDataSet) {
                for (Workout workout : monthDesc.itemDataSet) {
                    if (workout.getUploadStatus() != Enums.UploadStatus.Uploaded) {
                        linkedList.add(workout);
                    }
                }
            }
            unUploadCount = linkedList.size();
            Observable.from(linkedList).subscribeOn(Schedulers.io()).flatMap((Func1<Workout, Observable<Workout>>) workout2 -> {
                workout2.flushUploadState();
                return Observable.just(workout2);
            }).observeOn(AndroidSchedulers.mainThread()).subscribe((Action1<Workout>) workout2 -> {
                historyListAdapter.updateItem(workout2);
                unUploadCount--;
                if (unUploadCount == 0) {
                    checkRedDotView(historyListAdapter.getMonthDataSet());
                }
            });
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.history_choose_confirm) {
            ArrayList<Workout> selectedItem = historyListAdapter.getSelectedItem();
            long[] toMergeList = new long[selectedItem.size()];
            for (int i = 0; i < selectedItem.size() && selectedItem.get(i).getId() != null; i++) {
                toMergeList[i] = selectedItem.get(i).getId();
            }
            startActivityForResult(new Intent(this, WorkoutMergeListActivity.class)
                    .putExtra("workout_id_arrays", toMergeList), 2);
        }
    }
}